using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace ET
{
    /// <summary>
    /// 选择委托：从 某个类型的对象中 返回某个属性
    /// 【任何类型的属性：Id，Age，Name，Head】的值！
    /// </summary>
    /// <typeparam name="T">数据类型：Person</typeparam>
    /// <typeparam name="TKey">数据类型的属性的类型</typeparam>
    /// <param name="t">数据类型的对象：如 张三zs</param>
    /// <returns>zs.Id>1; zs.Name>“张三”; zs.Head>Head对象</returns>
    public delegate TKey SelectHandler<T, TKey>(T t);

    /// <summary>
    /// 查找委托：表示一个查找条件 =代表条件表达式！
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <param name="t">数据类型的对象</param>
    /// <returns>bool：true，false</returns>
    public delegate bool FindHandler<T>(T t);

    public static class ArrayExtend
    {
        #region ArrayHelper 数组工具扩展

        /// <summary>
        /// 1 升序排序方法
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <typeparam name="TKey">数据类型某个属性的类型</typeparam>
        /// <param name="array">对象集合</param>
        /// <param name="handler">
        /// 查找委托：从 某个类型的对象中 返回某个属性的值！
        /// </param>
        public static void OrderBy<T, TKey>(this T[] array, SelectHandler<T, TKey> handler)
            where TKey : IComparable<TKey>
        {
            for (int i = 0; i < array.Length - 1; i++)
            {
                for (int j = i + 1; j < array.Length; j++)
                {
                    if (handler(array[i]).CompareTo(handler(array[j])) > 0)
                    {
                        var temp = array[i];
                        array[i] = array[j];
                        array[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 比较两个数组是否相同
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="array"></param>
        /// <param name="arr"></param>
        /// <returns></returns>
        public static bool Compareto<T>(this T[] array, T[] arr) where T : IComparable<T>
        {
            bool ret = false;

            if (Enumerable.SequenceEqual(array, arr))
            {
                ret = true;
            }

            return ret;
        }


        /// <summary>
        /// 2 降序排序方法
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <typeparam name="TKey">数据类型某个属性的类型</typeparam>
        /// <param name="array">对象集合</param>
        /// <param name="handler">
        /// 查找委托：从 某个类型的对象中 返回某个属性的值！
        /// </param>
        public static void OrderByDescending<T, TKey>(this T[] array, SelectHandler<T, TKey> handler)
            where TKey : IComparable<TKey>
        {
            for (int i = 0; i < array.Length - 1; i++)
            {
                for (int j = i + 1; j < array.Length; j++)
                {
                    if (handler(array[i]).CompareTo(handler(array[j])) < 0)
                    {
                        var temp = array[i];
                        array[i] = array[j];
                        array[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 3 找最大的方法
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <typeparam name="TKey">数据类型某个属性的类型</typeparam>
        /// <param name="array">对象集合</param>
        /// <param name="handler">
        /// 查找委托：从 某个类型的对象中 返回某个属性的值！
        /// </param>
        public static T Max<T, TKey>(this T[] array, SelectHandler<T, TKey> handler) where TKey : IComparable<TKey>
        {
            T max = default(T);
            max = array[0];
            for (int i = 1; i < array.Length; i++)
            {
                if (handler(max).CompareTo(handler(array[i])) < 0)
                {
                    max = array[i];
                }
            }

            return max;
        }

        /// <summary>
        /// 4 找最小的方法
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <typeparam name="TKey">数据类型某个属性的类型</typeparam>
        /// <param name="array">对象集合</param>
        /// <param name="handler">
        /// 查找委托：从 某个类型的对象中 返回某个属性的值！
        /// </param>
        public static T Min<T, TKey>(this T[] array, SelectHandler<T, TKey> handler) where TKey : IComparable<TKey>
        {
            T min = default(T);
            min = array[0];
            for (int i = 1; i < array.Length; i++)
            {
                if (handler(min).CompareTo(handler(array[i])) > 0)
                {
                    min = array[i];
                }
            }

            return min;
        }

        /// <summary>
        /// 5 按照某个条件查找返回一个对象 Find
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="array">数据类型数组</param>
        /// <param name="handler">
        /// 查找委托：某个条件:多样的，写法很多 id=3 id!=3 id>3
        /// id>3&&Age>25&&.....
        /// </param>
        /// <returns>符合条件的一个对象或null或0</returns>
        public static T Find<T>(this T[] array, FindHandler<T> handler)
        {
            for (int i = 0; i < array.Length; i++)
            {
                if (handler(array[i]))
                {
                    return array[i];
                }
            }

            return default(T);
        }

        /// <summary>
        /// 6 按照某个条件查找返回所有对象 FindAll   
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="array">数据类型数组</param>
        /// <param name="handler">
        /// 查找委托：某个条件:多样的，写法很多 id=3 id!=3 id>3
        /// id>3&&Age>25&&.....
        /// </param>
        /// <returns>符合条件的所有对象或null或0</returns>
        public static T[] FindAll<T>(this T[] array,
            FindHandler<T> handler)
        {
            List<T> list = new List<T>();
            for (int i = 0; i < array.Length; i++)
            {
                if (handler(array[i]))
                {
                    list.Add(array[i]);
                }
            }

            return list.ToArray();
        }

        /// <summary>
        /// 7 选取数组中对象的某些成员形成一个独立的数组
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <typeparam name="TKey">数据类型的属性</typeparam>
        /// <param name="array">数据类型数组</param>
        /// <param name="handler">选择委托</param>
        /// <returns>新的数组</returns>
        public static TKey[] Select<T, TKey>(this T[] array,
            SelectHandler<T, TKey> handler)
        {
            TKey[] keys = new TKey[array.Length];
            for (int i = 0; i < array.Length; i++)
            {
                keys[i] = handler(array[i]);
            }

            return keys;
        }

        #endregion
    }
}